/* -----------------
* brief
* 1. this is code gen by tools
* 2. mvc code are driver by the model defined with the same filename,
	 for example:
	 there is a Xmodel struct define in xmodel.go file, after the script run (lego model-mvc module_name xmodel)
     it will auto create the code under the module's path
	 m --> xmodel.go
	 v --> view
	 c --> xmodel_ctrl
* 3. you should modify this code if it doesn't satisfy your purpose
*/

package controller

import (
	"encoding/json"
	"fmt"
	"github.com/chanxuehong/wechat/mch/pay"
	"github.com/mjiulee/lego"
	"github.com/mjiulee/lego/utils"
	"github.com/valyala/fasthttp"
	"saas_sys_base/common"
	. "saas_sys_base/modules/eshop/models"
	"saas_sys_base/modules/eshop/service"
	. "saas_sys_base/modules/orders/models"
	. "saas_sys_base/modules/orders/service"
	product "saas_sys_base/modules/product/service"
	. "saas_sys_base/modules/user/service"
	. "saas_sys_base/modules/wechat/service"
	"time"
)

type OrdersCtrl struct {
	service                 OrdersService
	shopService             service.EShopService
	logisticsCompanyService LogisticsCompanyService
	detailService           OrderDetailService
	specService             product.ProductSpecService
	addressService          ReceiveAddressService
	wxUserService           WxUserService
	wxWeappMchPayService    WxWeappMchPayService
	cartService             CartService
}

func init() {
	vc := new(OrdersCtrl)
	vc.wxWeappMchPayService = *NewWxWeappMchPayService()
	_ctrlList = append(_ctrlList, vc)
}

func (vc *OrdersCtrl) CtrlInfo() string {
	return "OrdersCtrl"
}

func (vc *OrdersCtrl) RoutInit() {
	// 列表页面
	lego.GET("/admin/Orders/listpage", vc.ListPage, lego.LEGO_SESSION_TYPE_ADMIN, false)
	lego.GET("/admin/Orders/listjson", vc.ListJson, lego.LEGO_SESSION_TYPE_ADMIN, false)
	// 编辑页面
	lego.GET("/admin/Orders/editpage", vc.GetEditPage, lego.LEGO_SESSION_TYPE_ADMIN, false)
	//lego.POST("/admin/Orders/editpage", vc.PostEditPage, lego.LEGO_SESSION_TYPE_ADMIN, false)
	// 删除
	//lego.POST("/admin/Orders/del", vc.DelRecode, lego.LEGO_SESSION_TYPE_ADMIN, false)

	//租户管理端接口
	lego.GET("/admin/Orders/listpage_saas", vc.ListPage_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)
	lego.GET("/admin/Orders/alllistjson_saas", vc.AllListJson_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)

	lego.GET("/admin/Orders/unpaylistpage_saas", vc.UnPayListPage_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)
	lego.GET("/admin/Orders/unpayistjson_saas", vc.UnPayListJson_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)

	lego.GET("/admin/Orders/paylistpage_saas", vc.PayListPage_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)
	lego.GET("/admin/Orders/payistjson_saas", vc.PayistJson_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)

	lego.GET("/admin/Orders/sendedlistpage_saas", vc.SendedListPage_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)
	lego.GET("/admin/Orders/sendedistjson_saas", vc.SendedListJson_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)

	lego.GET("/admin/Orders/finishlistpage_saas", vc.FinishListPage_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)
	lego.GET("/admin/Orders/finishistjson_saas", vc.FinishListJson_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)

	lego.GET("/admin/Orders/cancellistpage_saas", vc.CancelListPage_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)
	lego.GET("/admin/Orders/cancellistjson_saas", vc.CancelListJson_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)

	lego.GET("/admin/Orders/refundlistpage_saas", vc.RefundListPage_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)
	lego.GET("/admin/Orders/refundlistjson_saas", vc.RefundListJson_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)

	lego.GET("/admin/Orders/editpage_saas", vc.GetEditPage_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)
	lego.GET("/admin/Orders/getOrderDetail_saas", vc.GetOrderDetails_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)
	lego.GET("/admin/Orders/deliverypage_saas", vc.GetDelievryPage_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)
	lego.POST("/admin/Orders/delivery_saas", vc.Delievry_Saas, lego.LEGO_SESSION_TYPE_ADMIN, true)

	//租户小程序端接口
	lego.APIGET("/api/Orders/getalllistjson_saas", vc.AllListJson_Saas, true)
	lego.APIGET("/api/Orders/getpayistjson_saas", vc.PayistJson_Saas, true)
	lego.APIGET("/api/Orders/getrefundlistjson_saas", vc.RefundListJson_Saas, true)
	lego.APIGET("/api/Orders/getOrderDetail_saas", vc.GetOrderDetail_Saas, true)
	lego.APIPOST("/api/Orders/delivery_saas", vc.Delievry_Saas, true)

	//C端接口
	lego.APIGET("/api/mall/Orders/getalllistjson", vc.ListJson_ForMall, true)
	lego.APIGET("/api/mall/Orders/getOrderDetail", vc.GetOrderDetail, true)
	lego.APIPOST("/api/mall/Orders/cancelOrder", vc.CancelOrder, true)
	lego.APIPOST("/api/mall/Orders/submitSum", vc.SubmitSum, true)
	lego.APIPOST("/api/mall/Orders/submitOrder", vc.SubmitOrder, true)
	lego.APIPOST("/api/mall/Orders/advancePay", vc.AdvancePay, true)
	lego.APIPOST("/api/mall/Orders/testPay", vc.TestPay, true)

}

/* 列表接口
* params:
  ---
*/
func (vc *OrdersCtrl) ListJson(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := ""

	for {
		//:saas管理端使用代码，使用时将注释解开 sessionData := common.GetSessionData(&ctxExt)
		//:appwho := sessionData.AppTokenWho

		// 表单校验
		type ReqParams struct {
			Keyword string // 关键字查询
			Page    int    `vd:"$>=0"` // 分页
			PSize   int    `vd:"$>0"`  // 分页大小

			OrderField string
			Order      string `vd:"$=='' || $=='asc' || $=='desc'"`
		}
		req := ReqParams{
			Keyword:    string(ctxExt.Peek("keyword")),
			Page:       utils.BytesToInt(ctxExt.Peek("page")),
			PSize:      utils.BytesToInt(ctxExt.Peek("limit")),
			OrderField: string(ctxExt.Peek("order_field")),
			Order:      string(ctxExt.Peek("order")),
		}
		if err := lego.Validate(req); err != nil {
			code = 100
			msg = err.Error()
			break
		}

		// 业务查询
		if list, total, err := vc.service.ListOrders(req.Keyword, req.Page, req.PSize, req.OrderField, req.Order); err != nil {
			lego.LogError(err)
		} else {
			response["count"] = total
			response["data"] = list
		}
		break
	}

	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}

/* 添加数据记录
* params:
  ---
*/
func (vc *OrdersCtrl) ListPage(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量
		break
	}
	ctxExt.HTML("orders/view/Orders/list.html", data)
	return
}

/* 添加数据记录
* params:
  ---
*/
func (vc *OrdersCtrl) GetEditPage(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量

		type ReqParams struct {
			Id int64 // 记录id，为空则新建，否则为编辑
		}
		req := ReqParams{
			Id: utils.BytesToInt64(ctxExt.Peek("id")),
		}
		if err := lego.Validate(req); err != nil {
			break
		}
		target := vc.service.GetOrdersById(req.Id)
		data["detail"] = target
		break
	}
	ctxExt.HTML("orders/view/Orders/edit.html", data)
	return
}

func (vc *OrdersCtrl) AllListJson_Saas(ctx *fasthttp.RequestCtx) {
	vc.ListJson_Saas(ctx, AllOrder)
}

func (vc *OrdersCtrl) UnPayListJson_Saas(ctx *fasthttp.RequestCtx) {
	vc.ListJson_Saas(ctx, UnPayOrder)
}

func (vc *OrdersCtrl) PayistJson_Saas(ctx *fasthttp.RequestCtx) {
	vc.ListJson_Saas(ctx, PayOrderWaitDelivery)
}

func (vc *OrdersCtrl) SendedListJson_Saas(ctx *fasthttp.RequestCtx) {
	vc.ListJson_Saas(ctx, SendedOrder)
}

func (vc *OrdersCtrl) FinishListJson_Saas(ctx *fasthttp.RequestCtx) {
	vc.ListJson_Saas(ctx, FinishOrder)
}

func (vc *OrdersCtrl) CancelListJson_Saas(ctx *fasthttp.RequestCtx) {
	vc.ListJson_Saas(ctx, CancelOrder)
}

func (vc *OrdersCtrl) RefundListJson_Saas(ctx *fasthttp.RequestCtx) {
	vc.ListJson_Saas(ctx, RefundOrder)
}

//租户管理端 for saas ********
/* 列表接口
* params:
  ---
*/
func (vc *OrdersCtrl) ListJson_Saas(ctx *fasthttp.RequestCtx, orderStatus int) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := ""

	for {
		sessionData := common.GetSessionData(&ctxExt)
		appwho := sessionData.AppTokenWho

		// 表单校验
		type ReqParams struct {
			OrderCode   string // 关键字查询
			UserName    string //
			Mobile      string //
			BeginTime   string //
			EndTime     string //
			ProductName string //
			OrderType   int
			Page        int `vd:"$>=0"` // 分页
			PSize       int `vd:"$>0"`  // 分页大小

			OrderField string
			Order      string `vd:"$=='' || $=='asc' || $=='desc'"`
		}
		req := ReqParams{
			OrderCode:   string(ctxExt.Peek("order_code")),
			UserName:    string(ctxExt.Peek("user_name")),
			Mobile:      string(ctxExt.Peek("mobile")),
			BeginTime:   string(ctxExt.Peek("begin_time")),
			EndTime:     string(ctxExt.Peek("end_time")),
			ProductName: string(ctxExt.Peek("product_name")),
			OrderType:   utils.BytesToInt(ctxExt.Peek("order_type")),
			Page:        utils.BytesToInt(ctxExt.Peek("page")),
			PSize:       utils.BytesToInt(ctxExt.Peek("limit")),
			OrderField:  string(ctxExt.Peek("order_field")),
			Order:       string(ctxExt.Peek("order")),
		}
		if err := lego.Validate(req); err != nil {
			code = 100
			msg = err.Error()
			break
		}

		shops := vc.shopService.ListByTenandId(appwho.TenantId)
		shopIds := make([]int64, len(shops))

		for i, v := range shops {
			shopIds[i] = v.Id
		}

		// 业务查询
		if list, total, err := vc.service.ListOrdersByWho(appwho, req.OrderCode, req.UserName, req.Mobile, req.BeginTime, req.EndTime, req.ProductName, req.OrderType, shopIds, req.Page, req.PSize, req.OrderField, req.Order, orderStatus); err != nil {
			lego.LogError(err)
		} else {
			response["count"] = total
			response["data"] = list
		}
		break
	}

	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}

/* 添加数据记录
* params:
  ---
*/
func (vc *OrdersCtrl) ListPage_Saas(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量
		break
	}
	ctxExt.HTML("orders/view/Orders/list_saas.html", data)
	return
}

func (vc *OrdersCtrl) UnPayListPage_Saas(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量
		break
	}
	ctxExt.HTML("orders/view/Orders/unpay_list_saas.html", data)
	return
}

func (vc *OrdersCtrl) PayListPage_Saas(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量
		break
	}
	ctxExt.HTML("orders/view/Orders/pay_list_saas.html", data)
	return
}

func (vc *OrdersCtrl) SendedListPage_Saas(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量
		break
	}
	ctxExt.HTML("orders/view/Orders/sended_list_saas.html", data)
	return
}

func (vc *OrdersCtrl) FinishListPage_Saas(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量
		break
	}
	ctxExt.HTML("orders/view/Orders/finish_list_saas.html", data)
	return
}

func (vc *OrdersCtrl) CancelListPage_Saas(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量
		break
	}
	ctxExt.HTML("orders/view/Orders/cancel_list_saas.html", data)
	return
}

func (vc *OrdersCtrl) RefundListPage_Saas(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量
		break
	}
	ctxExt.HTML("orders/view/Orders/refund_list_saas.html", data)
	return
}

/* 添加数据记录
* params:
  ---
*/
func (vc *OrdersCtrl) GetEditPage_Saas(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量

		type ReqParams struct {
			Id int64 // 记录id，为空则新建，否则为编辑
		}
		req := ReqParams{
			Id: utils.BytesToInt64(ctxExt.Peek("id")),
		}
		if err := lego.Validate(req); err != nil {
			break
		}
		target := vc.service.GetOrdersById(req.Id)

		shops := vc.shopService.ListByTenandId(appwho.TenantId)
		//shopIds := make([]int64,len(shops))

		//for i,v := range  shops{
		//	shopIds[i] = v.Id
		//}

		anyFlag, err := utils.SliceAny(shops, func(elem interface{}) bool {
			v := elem.(*EShop)
			if v.Id == target.EShopId {
				return true
			}
			return false
		})

		if err != nil {
			break
		}
		if !anyFlag {
			break
		}

		data["detail"] = target
		break
	}
	ctxExt.HTML("orders/view/Orders/edit_saas.html", data)
	return
}

func (vc *OrdersCtrl) GetOrderDetails_Saas(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}

	response := make(map[string]interface{})
	code := 0
	msg := ""
	for {
		//sessionData := common.GetSessionData(&ctxExt) //
		//appwho := sessionData.AppTokenWho

		type ReqParams struct {
			Id int64 // 记录id，为空则新建，否则为编辑
		}
		req := ReqParams{
			Id: utils.BytesToInt64(ctxExt.Peek("order_id")),
		}
		if err := lego.Validate(req); err != nil {
			code = 100
			msg = "参数错误"
			break
		}
		orderDetails := vc.detailService.ListByOrderId(req.Id)
		response["data"] = orderDetails

		//response["specs"] = vc.specService.ListByProductId(req.Id)
		break
	}
	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}
/* 添加数据记录
* params:
  ---
*/
func (vc *OrdersCtrl) GetOrderDetail_Saas(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}

	response := make(map[string]interface{})
	code := 0
	msg := ""
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho

		type ReqParams struct {
			Id int64 // 记录id，为空则新建，否则为编辑
		}
		req := ReqParams{
			Id: utils.BytesToInt64(ctxExt.Peek("id")),
		}
		if err := lego.Validate(req); err != nil {
			code = 100
			msg = "参数错误"
			break
		}

		target := vc.service.GetOrdersById(req.Id)
		shops := vc.shopService.ListByTenandId(appwho.TenantId)
		//shopIds := make([]int64,len(shops))

		//for i,v := range  shops{
		//	shopIds[i] = v.Id
		//}

		anyFlag, err := utils.SliceAny(shops, func(elem interface{}) bool {
			v := elem.(*EShop)
			if v.Id == target.EShopId {
				return true
			}
			return false
		})

		if err != nil {
			code = 100
			msg = "参数错误"
			break
		}
		if !anyFlag {
			code = 100
			msg = "参数错误"
			break
		}
		target.OrderDetails = vc.detailService.ListByOrderId(req.Id)
		response["data"] = target

		//response["specs"] = vc.specService.ListByProductId(req.Id)
		break
	}
	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}

/* 添加数据记录
* params:
  ---
*/
func (vc *OrdersCtrl) GetDelievryPage_Saas(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量

		type ReqParams struct {
			Id int64 // 记录id，为空则新建，否则为编辑
		}
		req := ReqParams{
			Id: utils.BytesToInt64(ctxExt.Peek("id")),
		}
		if err := lego.Validate(req); err != nil {
			break
		}
		target := vc.service.GetOrdersById(req.Id)

		shops := vc.shopService.ListByTenandId(appwho.TenantId)
		//shopIds := make([]int64,len(shops))

		//for i,v := range  shops{
		//	shopIds[i] = v.Id
		//}

		anyFlag, err := utils.SliceAny(shops, func(elem interface{}) bool {
			v := elem.(*EShop)
			if v.Id == target.EShopId {
				return true
			}
			return false
		})

		if err != nil {
			break
		}
		if !anyFlag {
			break
		}

		data["orderId"] = req.Id
		break
	}
	ctxExt.HTML("orders/view/Orders/delivery_saas.html", data)
	return
}

func (vc *OrdersCtrl) Delievry_Saas(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})

	code := 0
	msg := ""
	for {
		sessionData := common.GetSessionData(&ctxExt)
		appwho := sessionData.AppTokenWho

		type DeliveryParam struct {
			Id          int64  `json:"id,string"`
			LogisticsId int64  `json:"logistics_id,string"`
			LogisticsNo string `json:"logistics_no"`
		}

		var deliveryParam DeliveryParam
		requestByte := ctxExt.PostBody()
		err := json.Unmarshal(requestByte, &deliveryParam)

		if err != nil {
			code = 100
			msg = "参数错误"
			break
		}

		target := vc.service.GetOrdersById(deliveryParam.Id)

		shops := vc.shopService.ListByTenandId(appwho.TenantId)
		//shopIds := make([]int64,len(shops))

		//for i,v := range  shops{
		//	shopIds[i] = v.Id
		//}

		anyFlag, err := utils.SliceAny(shops, func(elem interface{}) bool {
			v := elem.(*EShop)
			if v.Id == target.EShopId {
				return true
			}
			return false
		})

		if err != nil {
			code = 100
			msg = "参数错误"
			break
		}
		if !anyFlag {
			code = 100
			msg = "参数错误"
			break
		}

		if target.IfPay == common.STATE_NO {
			code = 100
			msg = "订单未支付"
			break
		}

		if target.IfDelivery == common.STATE_YES {
			code = 100
			msg = "订单已支付"
			break
		}

		logisticsCompany := vc.logisticsCompanyService.GetLogisticsCompanyById(deliveryParam.LogisticsId)

		if logisticsCompany == nil {
			code = 100
			msg = "参数错误"
			break
		}

		target.IfDelivery = common.STATE_YES
		target.LogisticsCompany = logisticsCompany.CompanyName
		target.LogisticsId = logisticsCompany.Id
		target.LogisticsNo = deliveryParam.LogisticsNo

		vc.service.UpdateOrders(target)

		break
	}

	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return

}

//c端 ********
/* 列表接口
* params:
  ---
*/
func (vc *OrdersCtrl) ListJson_ForMall(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := ""

	for {
		sessionData := common.GetSessionData(&ctxExt)
		appwho := sessionData.AppTokenWho

		// 表单校验
		type ReqParams struct {
			OrderCode   string // 关键字查询
			OrderType   int
			OrderStatus int
			Page        int `vd:"$>0"` // 分页
			PSize       int `vd:"$>0"` // 分页大小
			OrderField  string
			Order       string `vd:"$=='' || $=='asc' || $=='desc'"`
		}
		req := ReqParams{
			OrderCode:   string(ctxExt.Peek("order_code")),
			OrderType:   utils.BytesToInt(ctxExt.Peek("order_type")),
			OrderStatus: utils.BytesToInt(ctxExt.Peek("order_status")),
			Page:        utils.BytesToInt(ctxExt.Peek("page")),
			PSize:       utils.BytesToInt(ctxExt.Peek("limit")),
			OrderField:  string(ctxExt.Peek("order_field")),
			Order:       string(ctxExt.Peek("order")),
		}
		if err := lego.Validate(req); err != nil {
			code = 100
			msg = err.Error()
			break
		}

		shop := vc.shopService.GetEShopByTenantId(appwho.TenantId)

		// 业务查询
		if list, total, err := vc.service.ListOrdersByWhoForMall(appwho, req.OrderCode, req.OrderType, shop.Id, req.Page, req.PSize, req.OrderField, req.Order, req.OrderStatus); err != nil {
			lego.LogError(err)
		} else {

			if len(list) > 0 {
				orderIds := make([]int64, len(list))
				for i, v := range list {
					orderIds[i] = v.Id
				}

				var details = vc.detailService.ListByOrderIds(orderIds)
				for _, v := range list {
					orderDetails, _ := utils.SliceFindWhere(details, func(elem interface{}) bool {
						detail := elem.(*OrderDetail)
						if v.Id == detail.OrderId && detail.IfDel == 0 {
							return true
						}
						return false
					})

					v.OrderDetails = orderDetails.([]*OrderDetail)
				}
			}

			response["count"] = total
			response["data"] = list
		}
		break
	}

	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}

func (vc *OrdersCtrl) GetOrderDetail(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}

	response := make(map[string]interface{})
	code := 0
	msg := ""
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho

		type ReqParams struct {
			Id int64 // 记录id，为空则新建，否则为编辑
		}
		req := ReqParams{
			Id: utils.BytesToInt64(ctxExt.Peek("id")),
		}
		if err := lego.Validate(req); err != nil {
			code = 100
			msg = "参数错误"
			break
		}

		target := vc.service.GetOrdersByWho(appwho, req.Id)
		if target == nil {
			code = 100
			msg = "订单不存在"
			break
		}
		shop := vc.shopService.GetEShopByTenantId(appwho.TenantId)
		if target.EShopId != shop.Id {
			code = 100
			msg = "订单不存在"
			break
		}

		target.OrderDetails = vc.detailService.ListByOrderId(req.Id)
		response["data"] = target

		//response["specs"] = vc.specService.ListByProductId(req.Id)
		break
	}
	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}

//取消订单
func (vc *OrdersCtrl) CancelOrder(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}

	response := make(map[string]interface{})
	code := 0
	msg := ""
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho

		type ReqParams struct {
			Id int64 `json:"id,string"` // 记录id，为空则新建，否则为编辑
		}
		var req ReqParams
		requestByte := ctxExt.PostBody()
		err := json.Unmarshal(requestByte, &req)

		if err != nil {
			code = 100
			msg = "参数错误"
			break
		}

		target := vc.service.GetOrdersByWho(appwho, req.Id)
		if target == nil {
			code = 100
			msg = "订单不存在"
			break
		}

		shop := vc.shopService.GetEShopByTenantId(appwho.TenantId)
		if target.EShopId != shop.Id {
			code = 100
			msg = "订单不存在"
			break
		}

		if target.IfPay == common.STATE_YES {
			code = 100
			msg = "订单已支付不能取消"
			break
		}
		target.IfCancel = common.STATE_YES
		target.CancelTime = time.Now()
		vc.service.UpdateOrders(target)
		msg = "取消成功"
		//response["specs"] = vc.specService.ListByProductId(req.Id)
		break
	}
	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}

func (vc *OrdersCtrl) SubmitSum(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}

	response := make(map[string]interface{})
	code := 0
	msg := ""
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho

		type CartItem struct {
			ProductId int64 `json:"product_id,string"`
			SpecId    int64 `json:"spec_id,string"`
			Num       int   `json:"num"`
		}

		type ReqParams struct {
			OrderType int        `json:"order_type"`
			CartItems []*CartItem `json:"cart_items"` // 记录id，为空则新建，否则为编辑
		}
		var req ReqParams
		requestByte := ctxExt.PostBody()
		err := json.Unmarshal(requestByte, &req)

		if err != nil {
			code = 100
			msg = "参数错误"
			break
		}

		type SpecItem struct {
			SpecId       int64   `json:"spec_id,string"`
			ProductId    int64   `json:"product_id,string"`
			ProductName  string  `json:"product_name"`
			DefaultImage string  `json:"default_image"`
			SpecName     string  `json:"spec_name"`
			SellPrice    int64 `json:"sell_price"`
			Num          int     `json:"num"`
		}

		type SumResponce struct {
			ProductAmount int64    `json:"product_amount"`
			Postage       int64    `json:"postage"`
			RealAmount    int64    `json:"real_amount"`
			SpecItems     []SpecItem `json:"spec_items"`
		}

		sumResponce := new(SumResponce)
		sumResponce.SpecItems = make([]SpecItem, len(req.CartItems))

		specIds := make([]int64, len(req.CartItems))

		for i, v := range req.CartItems {
			specIds[i] = v.SpecId
		}

		shop := vc.shopService.GetEShopByTenantId(appwho.TenantId)
		specList := vc.specService.ListByIdsForShop(specIds, shop.Id)
		var sumPostage int64 = 0
		if req.OrderType == Delivery {
			//线上订单 需要计算运费
			sumPostage = 0
		}

		var sumAmount int64 = 0
		for i, v := range specList {
			cart, _ := utils.SliceFindFirstWhere(req.CartItems, func(elem interface{}) bool {
				item := elem.(*CartItem)
				if v.ProductSpec.Id == item.SpecId {
					return true
				}
				return false
			})
			cartItem := cart.(*CartItem)
			//未考虑会员卡优惠  后面需要考虑
			sumAmount = sumAmount + v.ProductSpec.SellPrice*int64(cartItem.Num)

			sumResponce.SpecItems[i].SellPrice = v.ProductSpec.SellPrice
			sumResponce.SpecItems[i].Num = cartItem.Num
			sumResponce.SpecItems[i].SpecId = v.ProductSpec.Id
			sumResponce.SpecItems[i].ProductName = v.Product.ProductName
			sumResponce.SpecItems[i].ProductId = v.Product.Id
			sumResponce.SpecItems[i].SpecName = v.ProductSpec.SpecName
			sumResponce.SpecItems[i].DefaultImage = v.Product.DefaultImage
		}

		sumResponce.Postage = sumPostage
		sumResponce.ProductAmount = sumAmount
		sumResponce.RealAmount = sumPostage + sumAmount

		response["data"] = sumResponce
		break
	}
	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}

func (vc *OrdersCtrl) SubmitOrder(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}

	response := make(map[string]interface{})
	code := 0
	msg := ""
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho

		type CartItem struct {
			ProductId int64 `json:"product_id,string"`
			SpecId    int64 `json:"spec_id,string"`
			Num       int   `json:"num"`
			CartId    int64 `json:"cart_id,string"`
		}

		type ReqParams struct {
			OrderType int        `json:"order_type"`
			IfCart    int        `json:"if_cart"`
			AddressId int64      `json:"address_id,string"`
			Remark    string     `json:"remark"`
			CartItems []*CartItem `json:"cart_items"` // 记录id，为空则新建，否则为编辑

		}
		var req ReqParams
		requestByte := ctxExt.PostBody()
		err := json.Unmarshal(requestByte, &req)

		if err != nil {
			code = 100
			msg = "参数错误"
			break
		}

		specIds := make([]int64, len(req.CartItems))

		for i, v := range req.CartItems {
			specIds[i] = v.SpecId
		}

		if req.IfCart == common.STATE_YES {
			vc.cartService.SubmitOrder(appwho, specIds)
		}

		shop := vc.shopService.GetEShopByTenantId(appwho.TenantId)
		specList := vc.specService.ListByIdsForShop(specIds, shop.Id)
		var sumPostage int64 = 0
		if req.OrderType == Delivery {
			//线上订单 需要计算运费
			sumPostage = 0
		}

		orderDetails := make([]*OrderDetail, len(specList))
		var sumAmount int64 = 0
		for i, v := range specList {
			cart, _ := utils.SliceFindFirstWhere(req.CartItems, func(elem interface{}) bool {
				item := elem.(*CartItem)
				if v.ProductSpec.Id == item.SpecId {
					return true
				}
				return false
			})
			cartItem := cart.(*CartItem)
			//未考虑会员卡优惠  后面需要考虑
			sumAmount = sumAmount + v.ProductSpec.SellPrice*int64(cartItem.Num)

			orderDetails[i] = new(OrderDetail)
			orderDetails[i].DefaultImage = v.Product.DefaultImage
			orderDetails[i].SpecName = v.ProductSpec.SpecName
			orderDetails[i].ProductId = v.Product.Id
			orderDetails[i].ProductName = v.Product.ProductName
			orderDetails[i].SpecId = v.ProductSpec.Id
			orderDetails[i].Num = cartItem.Num
			orderDetails[i].SellPrice = v.ProductSpec.SellPrice
			orderDetails[i].BarCode = v.ProductSpec.BarCode
			orderDetails[i].ItemNo = v.Product.ItemNo

		}

		order := new(Orders)
		order.PayableAmount = sumPostage + sumAmount
		order.ProAmount = sumAmount;
		order.Postage = sumPostage
		order.OrderType = req.OrderType
		order.Uid = appwho.Uid
		order.EShopId = shop.Id
		order.TenantId = appwho.TenantId
		order.OrderCode = ""
		order.BalanceAmout = 0
		order.Remark = req.Remark
		if order.OrderType == Delivery {
			//发货地址处理
			var address = vc.addressService.GetReceiveAddressByWho(appwho, req.AddressId)
			if address == nil {
				code = 100
				msg = "参数错误"
				break
			}
			order.UserName = address.Name
			order.Mobile = address.Mobile
			order.Province = address.Province
			order.City = address.City
			order.Area = address.Area
			order.Address = address.Address

		}

		vc.service.SaveOrders(order)
		for _, v := range orderDetails {
			v.OrderId = order.Id
			vc.detailService.SaveOrderDetail(v)
		}

		type Response struct {
			OrderId int64 `json:"order_id,string"`
		}

		var res = new(Response)
		res.OrderId = order.Id
		response["data"] = res

		break
	}
	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}

func (vc *OrdersCtrl) AdvancePay(ctx *fasthttp.RequestCtx) {

	ctxExt := lego.RequestCtxExtent{ctx}

	response := make(map[string]interface{})
	code := 0
	msg := ""

	type Response struct {
		UnifiedOrderResponse *pay.UnifiedOrderResponse
		PaySignResult        *pay.PaySignResult `json:",omitempty"`
	}

	var resp Response

	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho

		type ReqParams struct {
			OrderId   int64 `json:"order_id,string"`
			IfBalance int   `json:"if_balance"`
		}
		var req ReqParams
		requestByte := ctxExt.PostBody()
		err := json.Unmarshal(requestByte, &req)

		if err != nil {
			code = 100
			msg = "参数错误"
			break
		}

		target := vc.service.GetOrdersByWho(appwho, req.OrderId)
		if target == nil {
			code = 100
			msg = "订单不存在"
			break
		}

		shop := vc.shopService.GetEShopByTenantId(appwho.TenantId)
		if target.EShopId != shop.Id {
			code = 100
			msg = "订单不存在"
			break
		}

		if target.IfPay == common.STATE_YES {
			code = 100
			msg = "订单已支付"
			break
		}

		if target.IfCancel == common.STATE_YES {
			code = 100
			msg = "订单已取消"
			break
		}
		if req.IfBalance == common.STATE_YES {
			//未做余额判断
			code = 100
			msg = "余额不足"
			break
		}

		target.RealAmount = target.PayableAmount - target.DiscountFee

		vc.service.UpdateOrders(target)

		wxuser := vc.wxUserService.GetWxUserByUid(appwho.Uid) // TODO这里计划把他封装到调用它的service里，比如order模块里
		if wxuser == nil {
			code = -1
			msg = fmt.Sprintf("not found wxuser by uid<%d>", appwho.Uid)
			break
		}

		UnifiedOrderRequest := new(pay.UnifiedOrderRequest)
		UnifiedOrderRequest.OutTradeNo = utils.Int64ToString(target.Id)
		UnifiedOrderRequest.TotalFee = target.RealAmount
		UnifiedOrderRequest.TradeType = "JSAPI"
		UnifiedOrderRequest.Body = "test"
		UnifiedOrderRequest.OpenId = wxuser.OpenId

		if target.RealAmount == 0 {
			if err != nil {
				code = -1
				msg = "支付价格不能为0， 请再次确认价格"
				break
			}
		}

		result, paySignResult, err := vc.wxWeappMchPayService.UnifiedorderByAppWho(appwho, UnifiedOrderRequest, common.PAY_TO_SYS)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		//payRequest := new(*pay.MicroPayRequest)

		resp.UnifiedOrderResponse = result
		resp.PaySignResult = paySignResult
		response["data"] = resp

		break
	}
	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}


func (vc *OrdersCtrl) TestPay(ctx *fasthttp.RequestCtx){
	ctxExt := lego.RequestCtxExtent{ctx}

	response := make(map[string]interface{})
	code := 0
	msg := ""
	for {
		type ReqParams struct {
			OrderId   int64 `json:"order_id,string"`
		}
		var req ReqParams
		requestByte := ctxExt.PostBody()
		err := json.Unmarshal(requestByte, &req)

		if err != nil {
			code = 100
			msg = "参数错误"
			break
		}

		vc.service.TestPayAction(req.OrderId)


		break
	}

	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}